package com.siteseat.crudeq.broker.netty;

import java.io.UnsupportedEncodingException;

import org.apache.commons.lang3.StringUtils;

import com.siteseat.common.misc.IOHelper;
import com.siteseat.crudeq.common.raw.protocol.v1.ErrorCode;
import com.siteseat.crudeq.common.raw.protocol.v1.V1ResponseId;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;

/**
 *
 */
public class CodecHelper extends com.siteseat.crudeq.common.raw.protocol.v1.CodecHelper {

  /**
   * @param buf
   * @throws Exception
   */
  public static void writeError( Channel ch, ErrorCode errorCode ) {
    writeError( ch, errorCode, null );
  }

  /**
   * @param buf
   * @throws Exception
   */
  public static void writeError( Channel ch, ErrorCode errorCode, String detail ) {
    int bodySize = 4;

    boolean hasDetail = ( StringUtils.isBlank( detail ) == false );
    byte[] detailBytes = null;
    if( hasDetail ) {
      detailBytes = getEncodedText( detail );
      bodySize += detailBytes.length;
    } else {
      bodySize += 4;
    }

    ChannelBuffer output = ChannelBuffers.buffer( 1 + 4 + bodySize );

    output.writeByte( V1ResponseId.ERROR );
    output.writeInt( bodySize );
    output.writeInt( errorCode.id() );// body

    if( hasDetail ) {
      output.writeBytes( detailBytes );
    } else {
      output.writeInt( 0 );
    }

    ChannelFuture f = ch.write( output );
    f.addListener( ChannelFutureListener.CLOSE );
  }

  /**
   * @param buf
   * @param bodyBytes
   * @return
   * @throws InvalidRequestBodyException
   * @throws UnsupportedEncodingException
   */
  public static String readText( ChannelBuffer buf ) {
    byte[] tmp = readBytes( buf );
    return new String( tmp, 0, tmp.length, IOHelper.CHARSET );
  }

  public static byte[] readBytes( ChannelBuffer buf ) {

    int size = buf.readInt();
    if( size == 0 ) {
      return null;
    }

    byte[] r = new byte[size];
    buf.readBytes( r, 0, size );

    return r;
  }

  /**
   * @param buf
   * @param value
   * @throws UnsupportedEncodingException
   */
  public static int writeText( ChannelBuffer buf, String value ) { 
    byte[] bytes = value.getBytes( IOHelper.CHARSET );
    buf.writeBytes( bytes ); return bytes.length; 
  }
   

  /**
   * @param buf
   * @return
   * @throws InvalidRequestBodyException
   */
  public static boolean readBool( ChannelBuffer buf ) {
    return ( buf.readByte() == 1 ) ? true : false;
  }

  /**
   * @param buf
   * @param value
   * @throws UnsupportedEncodingException
   */
  public static int writeBool( ChannelBuffer buf, boolean value ) {
    buf.writeByte( value ? 1 : 0 );
    return 1;
  }

}
